package cn.tqfeiyang.smartadmin.commons.mybatis;

import cn.tqfeiyang.smartadmin.commons.exception.BusinessException;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

/**
 * 增强的Mapper
 *
 * @author tqfeiyang
 * @since 2024/9/27 8:19
 */
public interface MPBaseMapper<T> extends BaseMapper<T> {

    /**
     * 检查id是否存在
     *
     * @param id 主键id
     * @return id是否存在
     */
    default boolean isExists(Serializable id) {
        return selectById(id) != null;
    }

    /**
     * 检查id是否存在，不存在则返回异常
     *
     * @param id 主键id
     */
    default void validateExists(Serializable id) {
        if (selectById(id) == null) {
            throw new BusinessException("数据不存在({})", id);
        }
    }

    /**
     * 获取实体，如果不存在则抛出异常
     *
     * @param id
     * @return 实体，如果不存在则抛出异常
     */
    default T getOrElseThrow(Serializable id) {
        return Optional.of(selectById(id))
                .orElseThrow(() -> new BusinessException("数据不存在({})", id));
    }

    /**
     * 获取实体(深度)，如果不存在则抛出异常
     *
     * @param id
     * @return 实体，如果不存在则抛出异常
     */
    default T getDeepOrElseThrow(Serializable id) {
        return Optional.of(selectByIdDeep(id))
                .orElseThrow(() -> new BusinessException("数据不存在({})", id));
    }

    /**
     * 获取实体(深度)，转成响应类型，如果不存在则抛出异常
     *
     * @param id
     * @return 响应对象，如果不存在则抛出异常
     */
    default <R> R getDeepOrElseThrow(Serializable id, Class<R> resposneClass) {
        return Optional.of(selectByIdDeep(id, resposneClass))
                .orElseThrow(() -> new BusinessException("数据不存在({})", id));
    }

    /**
     * 根据 ID 查询实体，并读取关联数据
     *
     * @param id
     * @return 实体对象
     */
    default T selectByIdDeep(Serializable id) {
        return Relation.get(selectById(id));
    }

    /**
     * 根据 ID 查询实体，读取关联数据，转成响应类型
     *
     * @param id
     * @return 响应对象
     */
    default <R> R selectByIdDeep(Serializable id, Class<R> responseClass) {
        return Relation.get(selectById(id), responseClass);
    }

    /**
     * 根据 entity 条件，查询全部记录，读取关联数据
     *
     * @param queryWrapper
     * @return 实体列表
     */
    default List<T> selectListDeep(Wrapper<T> queryWrapper) {
        return Relation.get(selectList(queryWrapper));
    }

    /**
     * 根据 entity 条件，查询全部记录，读取关联数据，转成响应类型
     *
     * @param queryWrapper
     * @return 响应列表
     */
    default <R> List<R> selectListDeep(Wrapper<T> queryWrapper, Class<R> responseClass) {
        return Relation.get(selectList(queryWrapper), responseClass);
    }

    /**
     * 根据 entity 条件，查询一条记录，读取关联数据
     *
     * @param queryWrapper
     * @return 实体对象
     */
    default T selectOneDeep(Wrapper<T> queryWrapper) {
        return Relation.get(selectOne(queryWrapper));
    }

    /**
     * 根据 entity 条件，查询一条记录，读取关联数据，转成响应类型
     *
     * @param queryWrapper
     * @return 响应对象
     */
    default <R> R selectOneDeep(Wrapper<T> queryWrapper, Class<R> responseClass) {
        return Relation.get(selectOne(queryWrapper), responseClass);
    }
}
